import {Box2,Box3,BufferGeometry,Object3D,Vector2, Vector3} from "three/src/Three";
import Const from "../../application/constants/Const";
import { Point } from "../../renderExtension/types/Point";
import GeoUtils from "../../utils/GeoUtils";
import {LineGeometry} from "three/examples/jsm/lines/LineGeometry";
import { App, HtmlMarker } from "../../Docs";
import { LineWithWidth } from "../../Engine";
import GeometryUtil from "../../renderExtension/utils/GeometryUtil";

/**
* 线缓冲区分析
*/
export default class LineBufferAnalysis {
    private rangeArray = []; //缓冲区分析对象数据
    private bufferDistance; //缓冲范围
    private lineWithWidth: LineWithWidth; //缓冲区线

    /**
     * 构建线缓冲分析
     * @param param 线缓冲分析需要用到的参数
     * @param param.pointArray 线的顶点数组
     * @param param.objects 需要分析的对象数组
     * @param param.bufferDistance 缓冲范围
     * @example 
            var lineBufferAnalysis = new GE.LineBufferAnalysis({
                pointArray: pointArray, //线的点数组
                objects: poiArray, //参与缓冲区分析的对象数组
                bufferDistance: 50, //缓冲区分析向外扩展的距离
            });
            var bufferFilter = lineBufferAnalysis.bufferAnalysis(); 
     */
    public constructor(param: {pointArray: Array<Point>, objects: Array<Object3D>, bufferDistance: number}) {
        this.bufferDistance = (param.bufferDistance === undefined)?100:param.bufferDistance;

        this.initRangeArray(param);
        this.initMesh(param);
    }

    private initRangeArray(cfg){
        let self = this;
        cfg.objects.forEach(element => {
            let range:{ minX: number, minY: number, maxX: number, maxY: number } = { minX: 0, minY: 0, maxX: 0, maxY: 0 };

            if(element instanceof HtmlMarker){
                range.minX = element.position.x;
                range.minY = element.position.y;
                range.maxX = element.position.x;
                range.maxY = element.position.y;
            }else{
                var box = new Box3();
                box.setFromObject(element);
                
                range.minX = box.min.x;
                range.minY = box.min.y;
                range.maxX = box.max.x;
                range.maxY = box.max.y;
            }

            self.rangeArray.push(range);
        });

    }

    private initMesh(cfg){
        let lineData = {
            pointArray: cfg.pointArray,  //线的顶点数组
            color: '#00FA9A', //need to be updated
            lineWidth: this.bufferDistance,  //线的宽度
        };
        this.lineWithWidth = new LineWithWidth(lineData);
        App.getInstance().add(this.lineWithWidth);
    }

    public bufferAnalysis(){  
        let geoPointArray:{rectangleList: Array<Array<Vector2>>, circleList: Array<{center: Vector2, radius: number}>};
        geoPointArray = this.lineWithWidth.getGeoPointArray();
        let result = [];

        for (let i = 0; i < this.rangeArray.length; i++) {
            let isContain = false;
            let objectCenter = new Vector2((this.rangeArray[i].maxX + this.rangeArray[i].minX)/2, (this.rangeArray[i].maxY + this.rangeArray[i].minY)/2);
            label:
            for(let i=0; i<geoPointArray.rectangleList.length; i++){ //检测是否在矩形缓冲区内
                let rectangle = geoPointArray.rectangleList[i];
                if(GeometryUtil.isInShape(objectCenter, rectangle)){
                    isContain = true;
                    break label;
                }
            }

            if(!isContain){
                label2:
                for(let i=0; i<geoPointArray.circleList.length; i++){ //检测是否在圆形缓冲区内
                    let circle = geoPointArray.circleList[i];
                    let distance = objectCenter.distanceTo(circle.center);
                    if(distance <= circle.radius){
                        isContain = true;
                        break label2;
                    }
                }
            }
            
            result[i] = isContain;
        }
        return result;
    }

    public clear(){
        App.getInstance().remove(this.lineWithWidth);
    }
}